home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume20 / memlintok < prev    next >
Encoding:
Internet Message Format  |  1989-10-26  |  15.5 KB

  1. Subject:  v20i077:  A package to remove common lint/malloc complaints
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Bob Lewis <uunet!tessi!bobl>
  7. Posting-number: Volume 20, Issue 77
  8. Archive-name: memlintok
  9.  
  10. [  Various tools and tricks for doing this abound; might as well get one
  11.    in the archives.  Please don't submit any others unless they're
  12.    significantly better or different.  /r$  ]
  13.  
  14. "memlintok.h" is a header file that can be used to politely shut lint(1)
  15. up about casting results of memory allocation functions malloc(3),
  16. realloc(3), and calloc(3).  It also stops complaints about the argument of
  17. free(3).
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of shell archive."
  26. # Contents:  README Makefile good memlintok.3 memlintok.h t_memlintok.c
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f README -a "${1}" != "-c" ; then 
  29.   echo shar: Will not over-write existing file \"README\"
  30. else
  31. echo shar: Extracting \"README\" \(1747 characters\)
  32. sed "s/^X//" >README <<'END_OF_README'
  33. X"memlintok.h" is a header file that can be used to politely shut lint(1) up
  34. Xabout casting results of memory allocation functions malloc(3), realloc(3),
  35. Xand calloc(3).  It also stops complaints about the argument of free(3).
  36. X
  37. XCONTENTS
  38. X--------
  39. XFiles in this distribution are:
  40. X
  41. XREADME            you're reading it
  42. XMakefile        has several useful targets, including "install" and "test"
  43. Xgood            good results for "make test"
  44. Xmemlintok.3        man page
  45. Xmemlintok.h        the header file itself
  46. Xt_memlintok.c    a test/demo program
  47. X
  48. XDISCUSSION
  49. X----------
  50. XOne common way of ignoring lint errors is to do something like:
  51. X
  52. X    #ifdef lint
  53. X    #define malloc(arg) NULL
  54. X    #endif
  55. X
  56. XThe trouble with doing things this way is that lint will not then be able to
  57. Xcheck malloc's argument, so you could get away with something like:
  58. X
  59. X    char *p;
  60. X    char *q;
  61. X    ...
  62. X    p = malloc(q);
  63. X
  64. XThe macros here are a bit more sophisticated, so that the memory functions
  65. Xget invoked in a syntactically correct and properly-typed (although
  66. Xsemantically incorrect) fashion and the arguments get checked
  67. Xindependently.  The man page describes their use.
  68. X
  69. XThe file also includes a macro MR_ALLOC_LINTOK that is simply a compact form
  70. Xof the commonly-occurring code to allocate memory if a (typically static)
  71. Xpointer is NULL and to reallocate it if the pointer isn't NULL.
  72. X
  73. XThere are also macros to do some primitive exception handling of the memory
  74. Xallocation function.  See the man page for more on these.
  75. X
  76. XAs I developed it with my own resources, I'm releasing this code to the
  77. Xpublic domain.  I hereby deny any responsibility for its use or any damages
  78. Xresulting from same.
  79. X
  80. XNevertheless, if anyone has any problems with it, questions about it, or
  81. Ximprovements to it, please let me know.
  82. X
  83. X    - Bob Lewis
  84. X      bobl@tessi.uucp
  85. END_OF_README
  86. if test 1747 -ne `wc -c <README`; then
  87.     echo shar: \"README\" unpacked with wrong size!
  88. fi
  89. # end of overwriting check
  90. fi
  91. if test -f Makefile -a "${1}" != "-c" ; then 
  92.   echo shar: Will not over-write existing file \"Makefile\"
  93. else
  94. echo shar: Extracting \"Makefile\" \(951 characters\)
  95. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  96. X# $Header: Makefile,v 1.4 89/05/02 15:06:48 bobl Exp $
  97. X
  98. Xdefault: new
  99. X
  100. X#
  101. X#    This is where you want the header to go.  It might be advisable to
  102. X#    put it in some local directory rather than this default one...
  103. X#
  104. XHDR_DEST = /usr/include
  105. X
  106. X#
  107. X#    The man page goes here.  Again, you may have some local place to put it.
  108. X#
  109. XMAN_DEST = /usr/man/man3
  110. X
  111. XFILES = \
  112. X    README \
  113. X    Makefile \
  114. X    good \
  115. X    memlintok.3 \
  116. X    memlintok.h \
  117. X    t_memlintok.c
  118. X
  119. Xclean:
  120. X    rm -f t_memlintok new core a.out *.o memlintok.shar
  121. X
  122. Xnew:    t_memlintok
  123. X    t_memlintok >new
  124. X
  125. Xt_memlintok:    t_memlintok.c memlintok.h
  126. X    cc t_memlintok.c -o t_memlintok
  127. X
  128. Xtest:    new t_memlintok
  129. X    @echo "# comparing new results with known good ones:"
  130. X    diff new good
  131. X    @echo "# should be no lint errors:"
  132. X    lint -bachx t_memlintok.c
  133. X
  134. Xupdate:    new
  135. X    mv -f new good
  136. X
  137. Xshar: memlintok.shar
  138. X
  139. Xmemlintok.shar: $(FILES)
  140. X    shar $(FILES) >memlintok.shar
  141. X
  142. Xinstall: memlintok.h memlintok.3
  143. X    cp memlintok.h $(HDR_DEST)
  144. X    cp memlintok.3 $(MAN_DEST)
  145. X
  146. X    
  147. END_OF_Makefile
  148. if test 951 -ne `wc -c <Makefile`; then
  149.     echo shar: \"Makefile\" unpacked with wrong size!
  150. fi
  151. # end of overwriting check
  152. fi
  153. if test -f good -a "${1}" != "-c" ; then 
  154.   echo shar: Will not over-write existing file \"good\"
  155. else
  156. echo shar: Extracting \"good\" \(244 characters\)
  157. sed "s/^X//" >good <<'END_OF_good'
  158. X100 ints malloc'd
  159. X200 ints realloc'd
  160. X25 ints mr_alloc'd (realloc'd)
  161. X500 ints calloc'd
  162. X1000 ints mr_alloc'd (malloc'd)
  163. X50 ints calloc'd (or else)
  164. X100 ints malloc'd (or else)
  165. X200 ints realloc'd (or else)
  166. X400 ints mr_alloc'd (realloc'd) (or else)
  167. END_OF_good
  168. if test 244 -ne `wc -c <good`; then
  169.     echo shar: \"good\" unpacked with wrong size!
  170. fi
  171. # end of overwriting check
  172. fi
  173. if test -f memlintok.3 -a "${1}" != "-c" ; then 
  174.   echo shar: Will not over-write existing file \"memlintok.3\"
  175. else
  176. echo shar: Extracting \"memlintok.3\" \(4706 characters\)
  177. sed "s/^X//" >memlintok.3 <<'END_OF_memlintok.3'
  178. X.TH LINTOK 3 "2 May 1989"
  179. X.SH NAME
  180. Xmemlintok \- package to stop lint complaints about memory allocation
  181. X.SH SYNOPSIS
  182. X.LP
  183. X#include "memlintok.h"
  184. X.SH DESCRIPTION
  185. X.LP
  186. XThis package contains cpp macro definitions that
  187. Xstop lint from complaining about the memory management functions
  188. X.IR malloc (3),
  189. X.IR calloc (3),
  190. X.IR realloc (3),
  191. Xand
  192. X.IR free (3)
  193. X(hereafter, we'll call these the "\fI*alloc\fP(3)" functions),
  194. Xwhile at the same time performing checks of their arguments.
  195. XThere are two sets of macros defined here: one without exception handling
  196. X(like the
  197. X.IR *alloc (3)
  198. Xfunctions themselves) and one with.
  199. X.LP
  200. XThe macros without exception handling are:
  201. X.IP ""
  202. XCALLOC_LINTOK(ptr, nelem, type)
  203. X.br
  204. XMALLOC_LINTOK(ptr, nelem, type)
  205. X.br
  206. XREALLOC_LINTOK(ptr, nelem, type)
  207. X.br
  208. XFREE_LINTOK(ptr)
  209. X.br
  210. X.LP
  211. Xwhere "ptr" is a variable of type "type *".  After invoking any
  212. Xof the "*ALLOC_LINTOK" macros, "ptr" will either be NULL (if and
  213. Xonly if the
  214. Xunderlying function returned it) or it will point to an array of
  215. X"nelem" objects of type "type".
  216. X.LP
  217. XNote that the usage of MALLOC_LINTOK, CALLOC_LINTOK, and
  218. XREALLOC_LINTOK requires more than a name change.  An original
  219. Xcall of the form:
  220. X.IP
  221. Xptr = (type *) malloc(nelem * sizeof(type))
  222. X.LP
  223. Xmust be replaced by
  224. X.IP
  225. XMALLOC_LINTOK(ptr, nelem, type)
  226. X.LP
  227. Xand similarly for CALLOC_LINTOK and REALLOC_LINTOK.  All three
  228. Xmacros "return" values and may therefore be used as part of
  229. Xexpressions.
  230. X.LP
  231. XIf a macro's result is compared with NULL, lint will usually complain
  232. Xif NULL is cast to anything.  For example, this will produce a lint error:
  233. X.IP
  234. Xint *ia;
  235. X.br
  236. X ...
  237. X.br
  238. Xif (MALLOC_LINTOK(ia, 42, int) == (int *) NULL)
  239. X.br
  240. X ...
  241. X.LP
  242. XBut since uncast 0 (i.e., NULL) is always a valid pointer, it
  243. Xis unnecessary to cast it to anything.
  244. XRemoving the cast stops the lint complaint:
  245. X.IP
  246. X ...
  247. X.br
  248. Xif (MALLOC_LINTOK(ia, 42, int) == NULL)
  249. X.br
  250. X ...
  251. X.LP
  252. XIf the macro invocation doesn't appear within an expression,
  253. Xyou will need to cast the *ALLOC_LINTOK()
  254. Xinvocations to
  255. X.B void
  256. Xif you want to get rid of the
  257. X"*alloc returns value which is sometimes ignored"
  258. Xand
  259. X"*alloc returns value which is always ignored"
  260. Xmessages.
  261. X.LP
  262. XYou can mix invocations of these macros with calls to the original
  263. Xfunctions.  The only difference is in the lint behavior.
  264. X.LP
  265. XA common way of invoking the memory management functions is to call
  266. X.IR malloc ()
  267. Xif a
  268. Xpointer is NULL (usually the first time it's set) and
  269. X.IR realloc ()
  270. Xif it isn't NULL (usually on subsequent times).  The simple macro
  271. X.IP
  272. XMR_ALLOC_LINTOK(ptr, nelem, type)
  273. X.LP
  274. Xdoes this with MALLOC_LINTOK() and REALLOC_LINTOK().
  275. X.LP
  276. XSince memory allocation failure is often an exceptional condition,
  277. X"memlintok.h" also has definitions of four other useful macros that include
  278. Xexception handling:
  279. X.IP
  280. XCALLOC_OR_ELSE_LINTOK(ptr, nelem, type)
  281. X.br
  282. XMALLOC_OR_ELSE_LINTOK(ptr, nelem, type)
  283. X.br
  284. XREALLOC_OR_ELSE_LINTOK(ptr, nelem, type)
  285. X.br
  286. XMR_ALLOC_OR_ELSE_LINTOK(ptr, nelem, type)
  287. X.br
  288. X.LP
  289. XEach of these macros invokes the corresponding *ALLOC_LINTOK() macro and,
  290. Xif that macro fails, invokes another macro:
  291. X.IP
  292. XERROR_EXIT_LINTOK(nelem, size)
  293. X.LP
  294. XWhere "nelem" is the number of elements of "size" bytes attempting to be
  295. Xallocated.
  296. X.LP
  297. XA default ERROR_EXIT_LINTOK(nelem, size), which prints an informative
  298. Xmessage and dies, is also defined, but you are free to redefine it
  299. X(after including "memlintok.h" and before invoking any of the macros herein
  300. X-- remember to "#undef ERROR_EXIT_LINTOK" first)
  301. Xif you want to do your own error handling.
  302. X.SH "SEE ALSO"
  303. X.BR malloc (3),
  304. X.BR stdio (3S)
  305. X.SH NOTE
  306. X.LP
  307. X"memlintok.h" assumes NULL is defined in <stdio.h> (which is usually the case).
  308. X.LP
  309. XIt also assumes the cpp symbol "lint" is defined when and only when the
  310. Xcode is being passed through lint and not generating real executable code.
  311. X.LP
  312. XThese macros have been tested under SunOS, HP-UX, and Apollo DOMAIN/IX.
  313. X.SH BUGS
  314. X.LP
  315. XThese macros are intended for use with the dynamic
  316. Xallocation of single elements of fixed size (i.e. structs or typedefs)
  317. Xor variably-sized arrays of same.
  318. XIn the author's experience, this covers most uses of the
  319. X.IR \fI*alloc\fP (3)
  320. Xfunctions.
  321. XThe macros do not work well, however, when creating variably-sized single
  322. Xstructures that are not arrays.
  323. X.LP
  324. XAt least one version of
  325. X.IR lint (1)
  326. X(SunOS 4.0) complains when these macros
  327. Xare used with "void *" pointers.
  328. XIt needn't.
  329. X.LP
  330. XApollo DOMAIN/IX
  331. X.IR lint (1)
  332. Xgenerates several bogus (I believe) complaints about the default exception
  333. Xhandling macro.
  334. X.SH AUTHOR
  335. X.LP
  336. XBob Lewis (bobl@tessi.uucp) produced these macros using his own
  337. Xresources and hereby releases them to the public domain.
  338. XThe author will not be held responsible for their use, misuse,
  339. Xabuse, or any damages arising from same.
  340. END_OF_memlintok.3
  341. if test 4706 -ne `wc -c <memlintok.3`; then
  342.     echo shar: \"memlintok.3\" unpacked with wrong size!
  343. fi
  344. # end of overwriting check
  345. fi
  346. if test -f memlintok.h -a "${1}" != "-c" ; then 
  347.   echo shar: Will not over-write existing file \"memlintok.h\"
  348. else
  349. echo shar: Extracting \"memlintok.h\" \(2986 characters\)
  350. sed "s/^X//" >memlintok.h <<'END_OF_memlintok.h'
  351. X#ifndef INCLUDED_LINTOK
  352. X
  353. X/* $Header: memlintok.h,v 1.3 89/05/02 15:01:43 bobl Locked $ */
  354. X
  355. X/*
  356. X *    These definitions stop lint from complaining about malloc, calloc,
  357. X *    realloc, and free while at the same time performing checks of
  358. X *    their arguments.  See the memlintok(3) man page for more details.
  359. X *
  360. X *    Bob Lewis (bobl@tessi.uucp) produced these macros using his own
  361. X *    resources and hereby releases them to the public domain.
  362. X *    The author will not be held responsible for their use, misuse,
  363. X *    abuse, or any damages arising from same.
  364. X */
  365. X
  366. X#ifndef NULL
  367. X#include <stdio.h>
  368. X#endif
  369. X
  370. Xextern char *calloc();
  371. X#ifdef lint
  372. X#define CALLOC_LINTOK(ptr, nelem, type) \
  373. X    calloc((ptr = (type *) NULL, (unsigned) (nelem)), (unsigned) sizeof(type))
  374. X#else
  375. X#define CALLOC_LINTOK(ptr, nelem, type) \
  376. X    (ptr = (type *) calloc((unsigned) (nelem), (unsigned) sizeof(type)))
  377. X#endif
  378. X
  379. Xextern char *malloc();
  380. X#ifdef lint
  381. X#define MALLOC_LINTOK(ptr, nelem, type) \
  382. X    malloc((ptr = (type *) NULL, (unsigned) ((nelem) * sizeof(type))))
  383. X#else
  384. X#define MALLOC_LINTOK(ptr, nelem, type) \
  385. X    (ptr = (type *) malloc((unsigned) ((nelem) * sizeof(type))))
  386. X#endif
  387. X
  388. Xextern char *realloc();
  389. X#ifdef lint
  390. X#define REALLOC_LINTOK(ptr, nelem, type) \
  391. X    realloc( \
  392. X        (ptr = (type *) NULL, (char *) NULL), \
  393. X        (unsigned) ((nelem) * sizeof(type)))
  394. X#else
  395. X#define REALLOC_LINTOK(ptr, nelem, type) \
  396. X    (ptr = (type *) realloc( \
  397. X        (char *) ptr, \
  398. X        (unsigned) ((nelem) * sizeof(type))))
  399. X#endif
  400. X
  401. X/* common use of malloc/realloc -- use it or don't use it */
  402. X#define MR_ALLOC_LINTOK(ptr, nelem, type) \
  403. X    ( (ptr) == NULL \
  404. X        ? MALLOC_LINTOK(ptr, (nelem), type) \
  405. X        : REALLOC_LINTOK(ptr, (nelem), type) )
  406. X
  407. X/*
  408. X *    These next macros invoke CALLOC_LINTOK, MALLOC_LINTOK, REALLOC_LINTOK,
  409. X *    and MR_ALLOC_LINTOK with an error exit if they fail.
  410. X *
  411. X *    If you want to handle your own memory allocation errors, just
  412. X *    "#undef ERROR_EXIT_LINTOK" and define your own.
  413. X */
  414. X#define ERROR_EXIT_LINTOK(nelem, size) \
  415. X    { \
  416. X        (void) fprintf(stderr, \
  417. X            "Memory allocation of %d * %d bytes on line %d of \"%s\" failed.\n", \
  418. X            (nelem), (size), __LINE__, __FILE__); \
  419. X        exit(1); \
  420. X    }
  421. X
  422. X#define CALLOC_OR_ELSE_LINTOK(ptr, nelem, type) \
  423. X    { \
  424. X        if (CALLOC_LINTOK(ptr, (nelem), type) == NULL) \
  425. X            ERROR_EXIT_LINTOK((nelem), sizeof(type)); \
  426. X    }
  427. X
  428. X#define MALLOC_OR_ELSE_LINTOK(ptr, nelem, type) \
  429. X    { \
  430. X        if (MALLOC_LINTOK(ptr, (nelem), type) == NULL) \
  431. X            ERROR_EXIT_LINTOK((nelem), sizeof(type)); \
  432. X    }
  433. X
  434. X#define REALLOC_OR_ELSE_LINTOK(ptr, nelem, type) \
  435. X    { \
  436. X        if (REALLOC_LINTOK(ptr, (nelem), type) == NULL) \
  437. X            ERROR_EXIT_LINTOK((nelem), sizeof(type)); \
  438. X    }
  439. X
  440. X#define MR_ALLOC_OR_ELSE_LINTOK(ptr, nelem, type) \
  441. X    { \
  442. X        if (MR_ALLOC_LINTOK(ptr, (nelem), type) == NULL) \
  443. X            ERROR_EXIT_LINTOK((nelem), sizeof(type)); \
  444. X    }
  445. X
  446. Xextern free();
  447. X#ifdef lint
  448. X#define FREE_LINTOK(ptr) \
  449. X    free((ptr = NULL, (char *) NULL))
  450. X#else
  451. X#define FREE_LINTOK(ptr) \
  452. X    free((char *) ptr)
  453. X#endif
  454. X
  455. X/* We could have a "CFREE_LINTOK", but what's the point? */
  456. X
  457. X#define INCLUDED_LINTOK
  458. X#endif
  459. X
  460. END_OF_memlintok.h
  461. if test 2986 -ne `wc -c <memlintok.h`; then
  462.     echo shar: \"memlintok.h\" unpacked with wrong size!
  463. fi
  464. # end of overwriting check
  465. fi
  466. if test -f t_memlintok.c -a "${1}" != "-c" ; then 
  467.   echo shar: Will not over-write existing file \"t_memlintok.c\"
  468. else
  469. echo shar: Extracting \"t_memlintok.c\" \(1438 characters\)
  470. sed "s/^X//" >t_memlintok.c <<'END_OF_t_memlintok.c'
  471. X/* $Header: t_memlintok.c,v 1.3 89/05/02 15:07:08 bobl Exp $ */
  472. X
  473. X#include <stdio.h>
  474. X
  475. X#include "memlintok.h"
  476. X
  477. Xmain()
  478. X{
  479. X    int *p, *q;
  480. X
  481. X    if (MALLOC_LINTOK(p, 100, int) == NULL)
  482. X        fail("can't malloc 100 ints\n");
  483. X    else
  484. X        succeed("100 ints malloc'd\n");
  485. X
  486. X    (void) REALLOC_LINTOK(p, 200, int);
  487. X    if (p == NULL)
  488. X        fail("can't realloc 200 ints\n");
  489. X    else
  490. X        succeed("200 ints realloc'd\n");
  491. X
  492. X    if (MR_ALLOC_LINTOK(p, 25, int) == NULL)
  493. X        fail("can't mr_alloc (realloc) 25 ints\n");
  494. X    else
  495. X        succeed("25 ints mr_alloc'd (realloc'd)\n");
  496. X
  497. X    if (CALLOC_LINTOK(q, 500, int) == NULL)
  498. X        fail("can't calloc 500 ints\n");
  499. X    else
  500. X        succeed("500 ints calloc'd\n");
  501. X    q[0] = 0;
  502. X    FREE_LINTOK(q);
  503. X
  504. X    FREE_LINTOK(p);
  505. X    p = NULL;
  506. X    if (MR_ALLOC_LINTOK(p, 1000, int) == NULL)
  507. X        fail("can't mr_alloc (malloc) 1000 ints\n");
  508. X    else
  509. X        succeed("1000 ints mr_alloc'd (malloc'd)\n");
  510. X
  511. X    CALLOC_OR_ELSE_LINTOK(p, 50, int);
  512. X    succeed("50 ints calloc'd (or else)\n");
  513. X    MALLOC_OR_ELSE_LINTOK(p, 100, int);
  514. X    succeed("100 ints malloc'd (or else)\n");
  515. X    REALLOC_OR_ELSE_LINTOK(p, 200, int);
  516. X    succeed("200 ints realloc'd (or else)\n");
  517. X
  518. X#undef ERROR_EXIT_LINTOK
  519. X#define ERROR_EXIT_LINTOK(nelem, size) \
  520. X    fail("memory allocation failed\n");
  521. X
  522. X    MR_ALLOC_OR_ELSE_LINTOK(p, 400, int);
  523. X    succeed("400 ints mr_alloc'd (realloc'd) (or else)\n");
  524. X
  525. X    exit(0);
  526. X    return 0;    /* shuts up HP-UX lint */
  527. X}
  528. X
  529. Xfail(s)
  530. X    char *s;
  531. X{
  532. X    fputs(s, stdout);
  533. X    exit(1);
  534. X}
  535. X
  536. Xsucceed(s)
  537. X    char *s;
  538. X{
  539. X    fputs(s, stdout);
  540. X    return;
  541. X}
  542. END_OF_t_memlintok.c
  543. if test 1438 -ne `wc -c <t_memlintok.c`; then
  544.     echo shar: \"t_memlintok.c\" unpacked with wrong size!
  545. fi
  546. # end of overwriting check
  547. fi
  548. echo shar: End of shell archive.
  549. exit 0
  550.  
  551.